﻿// Type: FluentNHibernate.Automapping.Steps.IdentityStep
// Assembly: FluentNHibernate, Version=1.2.0.712, Culture=neutral, PublicKeyToken=8aa435e3cb308880
// Assembly location: e:\mydoc\visual studio 2010\Projects\NHibernateTest\NHibernateTest\ThirdPart\FluentNHibernate.dll

using FluentNHibernate;
using FluentNHibernate.Automapping;
using FluentNHibernate.Mapping;
using FluentNHibernate.MappingModel;
using FluentNHibernate.MappingModel.ClassBased;
using FluentNHibernate.MappingModel.Identity;
using System;

namespace FluentNHibernate.Automapping.Steps
{
  public class IdentityStep : IAutomappingStep
  {
    private readonly IAutomappingConfiguration cfg;

    public IdentityStep(IAutomappingConfiguration cfg)
    {
      this.cfg = cfg;
    }

    public bool ShouldMap(Member member)
    {
      return this.cfg.IsId(member);
    }

    public void Map(ClassMappingBase classMap, Member member)
    {
      if (!(classMap is ClassMapping))
        return;
      IdMapping mapping = new IdMapping()
      {
        ContainingEntityType = classMap.Type
      };
      mapping.AddDefaultColumn(new ColumnMapping()
      {
        Name = member.Name
      });
      mapping.Name = member.Name;
      mapping.Type = new TypeReference(member.PropertyType);
      mapping.Member = member;
      mapping.SetDefaultValue<GeneratorMapping>("Generator", this.GetDefaultGenerator(member));
      this.SetDefaultAccess(member, mapping);
      ((ClassMapping) classMap).Id = (IIdentityMapping) mapping;
    }

    private void SetDefaultAccess(Member member, IdMapping mapping)
    {
      Access access = MemberAccessResolver.Resolve(member);
      if (access != Access.Property && access != Access.Unset)
        mapping.SetDefaultValue<string>("Access", access.ToString());
      if (!member.IsProperty || member.CanWrite)
        return;
      mapping.SetDefaultValue<string>("Access", this.cfg.GetAccessStrategyForReadOnlyProperty(member).ToString());
    }

    private GeneratorMapping GetDefaultGenerator(Member property)
    {
      GeneratorMapping mapping = new GeneratorMapping();
      GeneratorBuilder generatorBuilder = new GeneratorBuilder(mapping, property.PropertyType);
      if (property.PropertyType == typeof (Guid))
        generatorBuilder.GuidComb();
      else if (property.PropertyType == typeof (int) || property.PropertyType == typeof (long))
        generatorBuilder.Identity();
      else
        generatorBuilder.Assigned();
      return mapping;
    }
  }
}
